package com.winsdom.service.count.impl;

import com.winsdom.entity.BillingMain;
import com.winsdom.entity.Bills;
import com.winsdom.entity.PrestoreRecord;
import com.winsdom.entity.count.ManualPostingRequest;
import com.winsdom.mapper.count.ManualPostingMapper;
import com.winsdom.service.count.ManualPostingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ManualPostingServiceImpl implements ManualPostingService {

    @Autowired
    private ManualPostingMapper manualPostingMapper;

    private static final Long BILL_NUMBER = 3141592653589793L;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void generateBills(ManualPostingRequest request) {
        for (ManualPostingRequest.Record record : request.getRecords()) {
            // 1. 获取计费主表信息
            BillingMain billingMain = manualPostingMapper.getBillingMainByDetailId(record.getDetailId());
            if (billingMain == null) {
                throw new RuntimeException("未找到对应的计费主表记录");
            }

            // 2. 获取客户的预存记录
            List<PrestoreRecord> prestoreRecords = manualPostingMapper.getPrestoreRecordsByCustomerId(billingMain.getCustomerId());
            
            // 3. 计算预存抵扣
            BigDecimal receivableAmount = record.getReceivableAmount();
            BigDecimal deductionAmount = BigDecimal.ZERO;
            BigDecimal offsetAmount = BigDecimal.ZERO;

            // 按金额从小到大排序预存记录
            prestoreRecords.sort(Comparator.comparing(PrestoreRecord::getAmount));

            // 先使用专项预存
            for (PrestoreRecord prestoreRecord : prestoreRecords.stream()
                    .filter(p -> p.getPrestoreType() > 0 && p.getStatus() == 1)
                    .collect(Collectors.toList())) {
                if (receivableAmount.compareTo(BigDecimal.ZERO) <= 0) break;

                BigDecimal availableAmount = prestoreRecord.getAmount();
                if (availableAmount.compareTo(receivableAmount) >= 0) {
                    deductionAmount = deductionAmount.add(receivableAmount);
                    prestoreRecord.setAmount(availableAmount.subtract(receivableAmount));
                    receivableAmount = BigDecimal.ZERO;
                } else {
                    deductionAmount = deductionAmount.add(availableAmount);
                    receivableAmount = receivableAmount.subtract(availableAmount);
                    prestoreRecord.setAmount(BigDecimal.ZERO);
                }

                if (prestoreRecord.getAmount().compareTo(BigDecimal.ZERO) == 0) {
                    prestoreRecord.setStatus(0);
                }
                manualPostingMapper.updatePrestoreRecord(prestoreRecord);
            }

            // 如果还有未抵扣完的金额，使用通用预存
            if (receivableAmount.compareTo(BigDecimal.ZERO) > 0) {
                for (PrestoreRecord prestoreRecord : prestoreRecords.stream()
                        .filter(p -> p.getPrestoreType() == 0 && p.getStatus() == 1)
                        .collect(Collectors.toList())) {
                    if (receivableAmount.compareTo(BigDecimal.ZERO) <= 0) break;

                    BigDecimal availableAmount = prestoreRecord.getAmount();
                    if (availableAmount.compareTo(receivableAmount) >= 0) {
                        deductionAmount = deductionAmount.add(receivableAmount);
                        prestoreRecord.setAmount(availableAmount.subtract(receivableAmount));
                        receivableAmount = BigDecimal.ZERO;
                    } else {
                        deductionAmount = deductionAmount.add(availableAmount);
                        receivableAmount = receivableAmount.subtract(availableAmount);
                        prestoreRecord.setAmount(BigDecimal.ZERO);
                    }

                    if (prestoreRecord.getAmount().compareTo(BigDecimal.ZERO) == 0) {
                        prestoreRecord.setStatus(0);
                    }
                    manualPostingMapper.updatePrestoreRecord(prestoreRecord);
                }
            }

            // 4. 生成账单
            Bills bill = new Bills();
            bill.setBillNumber(BILL_NUMBER);
            bill.setBillingMainId(billingMain.getId());
            bill.setBillType(1);
            bill.setCollectorName(record.getChargeObject());
            bill.setNotifyStatus(0);
            bill.setInvoiceMethod(3);
            bill.setInvoiceStatus(0);
            bill.setLateFeeAmount(BigDecimal.ZERO);
            bill.setDeductionAmount(deductionAmount);
            
            // 设置欠费状态和金额
            if (receivableAmount.compareTo(BigDecimal.ZERO) > 0) {
                bill.setArrearsStatus(1);
                bill.setArrearsAmount(receivableAmount);
                bill.setOffsetAmount(receivableAmount);
            } else {
                bill.setArrearsStatus(2);
                bill.setArrearsAmount(BigDecimal.ZERO);
                bill.setOffsetAmount(BigDecimal.ZERO);
            }

            manualPostingMapper.insertBill(bill);

            // 5. 更新计费主表状态为已入账
            billingMain.setStatus(2);
            manualPostingMapper.updateBillingMain(billingMain);
        }
    }
} 